package threadpool;

import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @description:
 * @author: walt-zhong
 * @createDate: 2021/8/11
 */
public class MyThreadPoolExector {
    private static final String TAG = "MyThreadPoolExector";
    private int CPU_COUNT = Runtime.getRuntime().availableProcessors();
    private int CORE_POOL_SIZE = Math.max(2,Math.min(CPU_COUNT-1,4));
    private int MAX_POOL_SIZE = CPU_COUNT*2 - 1;
    private int KEEP_LIVE_TIME = 5;
    private MyThreadFactory myThreadFactory = new MyThreadFactory();
    private final ThreadPoolExecutor executor;

    private MyThreadPoolExector(){
        executor = new ThreadPoolExecutor(CORE_POOL_SIZE, MAX_POOL_SIZE, KEEP_LIVE_TIME, TimeUnit.SECONDS,
                new LinkedBlockingDeque<>(), myThreadFactory);
        executor.allowCoreThreadTimeOut(true);
    }

    private static volatile MyThreadPoolExector sInstance;

    public static MyThreadPoolExector getInstance(){
        if(null == sInstance){
            synchronized (MyThreadPoolExector.class){
                if(null == sInstance){
                    sInstance = new MyThreadPoolExector();
                }
            }
        }

        return sInstance;
    }

    public ThreadPoolExecutor getExecutor(){
        return executor;
    }

    public void execute(String name,Runnable r){
        myThreadFactory.setName(name);
        executor.execute(r);
    }

    public void shutdown(){
        executor.shutdown();
    }




    private static class MyThreadFactory implements ThreadFactory {
        String name = null;
        public void setName(String name){
            this.name = name;
        }

        @Override
        public Thread newThread(Runnable r) {
            if(name == null){
                setName(TAG);
            }
            Thread thread = new Thread(r,name);
            thread.setPriority(Thread.NORM_PRIORITY);
            return thread;
        }
    }
}
